package com.oscar.ehome.utils.dowload.dowload;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Binder;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;

import com.oscar.ehome.utils.dowload.entity.TaskInfo;
import com.oscar.ehome.utils.dowload.progressbar.RoundProgressBar;
import com.oscar.ehome.utils.util.CommonUtils;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.LinkedList;
import java.util.Observer;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DownloadService extends Service {
    private boolean tag = true;
    public static final String ACTION_START = "start";
    public static final String ACTION_STOP = "stop";
    public static final String ACTION_UPDATE = "update";
    public static final String ACTION_FINISHED = "finished";
    public static final String EXTRA_FILE_NAME = "extra_file_name";
    public static final String EXTRA_DOWNLOAD_URL = "extra_url";
    private static final String DOWNLOAD_FILE = "Download";
    /**
     * cpu核心数默认值
     */
    private static final int DEFAULT_CPU_CORES = 2;

    private static final int DEFAULT_CPU_CORE = 3;

    private static final int DIWLOAD_ERROY = 56;

    private final int MSG_INIT = 0x01;
    private final int MSG_DOWNLOAD_FINISHED = 0x02;
    /**
     * 服务绑定
     **/
    private Binder mBinder;
    /*** 线程池 **/
    private ExecutorService mThreadPool;
    /*** 下载任务列表 **/
    private LinkedList<DownloadTask> mListTask;
    /*** 广播接收者 **/
    private BroadcastReceiver mReceiver;
    private Timer mTimer;
    private TimerTask mTask;
    private int time = 5 * 1000;
    TaskInfo infos;
    int lenths;

    OnDownload download_message;
    String dowload_id = "";

    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case DEFAULT_CPU_CORE:
                    if (CommonUtils.isNetConn(DownloadService.this)) {
                        if (!tag) {
                            tag = true;
                            OnDownload download = infos.getDownload();
                            download.onNetwork(tag);
                        }
                    } else {
                        if (tag) {
                            tag = false;
                            if (infos != null) {
                                if (infos.getDownload() != null) {
                                    OnDownload download = infos.getDownload();
                                    download.onNetwork(tag);
                                }
                            }
                        }
                    }
                    break;
                case DIWLOAD_ERROY:// 下载失败
                    download_message.onErroy(dowload_id); // 执行回调，更新下载进度
                    break;
                // start 下载任务初始化成功
                case MSG_INIT:// 4
                    infos = (TaskInfo) msg.obj;
                    lenths = 1;
                    DownloadTask task = new DownloadTask(DownloadService.this, infos, mThreadPool, lenths); // 建立下载任务
                    mListTask.add(task);
                    task.downlaod(); // 下载
                    break;
                // end 下载任务初始化成功
                // start 下载完成删除相应的任务
                case MSG_DOWNLOAD_FINISHED:
                    String url = (String) msg.obj;
                    for (DownloadTask task1 : mListTask) {
                        if (task1.getUrl().equals(url)) {
                            mListTask.remove(task1);
                            break;
                        }
                    }
                    break;
                // end 下载完成删除相应的任务
            }
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();
        if (CommonUtils.isNetConn(DownloadService.this)) {
            tag = true;
        } else {
            tag = false;
        }
        startTime();
        mThreadPool = Executors.newFixedThreadPool(getNumberOfCPUCores()); // 初始化线程
        mListTask = new LinkedList<DownloadTask>(); // 初始化任务列表
        registerReceiver(); // 注册广播
    }

    public void addObservable(String url, Observer obs) {
        DownloadTask Tn = null;
        for (DownloadTask info : mListTask) {
            if (info.getUrl().equals(url)) {
                Tn = info;
                break;
            }
        }

        if (Tn != null) {
            Tn.addObserver(obs);
        }
    }

    private void startTime() {
        mTimer = new Timer();
        mTask = new TimerTask() {
            @Override
            public void run() {
                mHandler.sendMessage(mHandler.obtainMessage(DEFAULT_CPU_CORE));
            }
        };
        mTimer.schedule(mTask, 0, time);
    }

    @Override
    public IBinder onBind(Intent intent) {
        if (null == mBinder) {
            mBinder = new DownloadBinder();
        }
        return mBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // start 停止所有在执行的任务
        for (DownloadTask task1 : mListTask) {
            task1.pause();
        }
        mThreadPool.shutdown(); // 关闭线程池
        // end 停止所有在执行的任务
        unregisterReceiver(mReceiver); // 注销广播

    }

    @Override
    public void onLowMemory() {
        // start 停止所有在执行的任务
        for (DownloadTask task1 : mListTask) {
            task1.pause();
        }
        // end 停止所有在执行的任务
        super.onLowMemory();
    }

    /**
     * 绑定服务类
     */
    public class DownloadBinder extends Binder {
        public DownloadService getService() {
            return DownloadService.this;
        }
    }

    /**
     * 注册广播
     */
    private void registerReceiver() {
        mReceiver = new DownloadFinishedReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_FINISHED);
        registerReceiver(mReceiver, filter);
    }

    /**
     * 下载
     *
     * @param url
     * @param download
     */
    public void download(String url, OnDownload download, String bookid, RoundProgressBar pb) {
        // TaskInfo info = new TaskInfo(url,null,null,0,download);
        download(url, null, null, download, bookid, pb);

    }

    public void download(String url, String filePath, OnDownload download, String bookid, RoundProgressBar pb) {
        TaskInfo info = new TaskInfo(url, filePath, null, 0, download, bookid, pb);
        download(url, filePath, null, download, bookid, pb);
    }

    public void download(String url, String filePath, String fileName, OnDownload download, String bookid, RoundProgressBar pb) {
        TaskInfo info = new TaskInfo(url, filePath, fileName, 0, download, bookid, pb);
        download(info);

    }

    /**
     * 下载 首先查找任务列表中对应的任务，如果没有找到则初始化新的下载任务
     *
     * @param info 下载任务信息
     */
    public void download(TaskInfo info) {
        // start 查找任务列表中对应的任务
        for (DownloadTask task1 : mListTask) {// 2
            if (task1.getUrl().equals(info.getUrl())) {
                if (task1.isPaused()) {
                    task1.restart(); // 任务已经停止，重新开始
                }
                return;
            }
        }
        // end 查找任务列表中对应的任务

        // 初始化新的下载任务
        InitThread thread = new InitThread(info);

        Log.d("vivi", "threadid====" + thread.getId());

        if (!mThreadPool.isShutdown()) {
            mThreadPool.execute(thread);
        }

    }

    /**
     * 停止任务
     *
     * @param url 下载链接
     */
    public void pause(String url) {
        // start 查找下载任务，停止响应的下载任务
        for (DownloadTask task1 : mListTask) {
            if (task1.getUrl().equals(url)) {
                task1.pause();
                return;
            }
        }
        // end 查找下载任务，停止响应的下载任务
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        return super.onStartCommand(intent, flags, startId);
    }

    class InitThread extends Thread {
        TaskInfo taskInfo;

        public InitThread(TaskInfo taskInfo) {
            this.taskInfo = taskInfo;
        }

        @Override
        public void run() {
            super.run();
            try {// 3
                download_message = taskInfo.getDownload();
                URL url = new URL(taskInfo.getUrl());
                HttpURLConnection con = (HttpURLConnection) url.openConnection();
                con.setRequestMethod("GET");
                con.setConnectTimeout(5000);
                if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    int len = con.getContentLength(); // 文件的总长度


                    taskInfo.setLenght(len);
                    if (len <= 0) {
                        return;
                    }
                    String downloadUrl = taskInfo.getUrl();
                    // start 设置存放文件的路径
                    String filePath = taskInfo.getFilePath();
                    if (TextUtils.isEmpty(filePath)) { // 没有设置路径
                        filePath = getFilePath(); // 获取默认的路径
                    } else {
                        File file = new File(filePath);
                        if (!file.exists()) { // 确保存在相应的文件夹
                            file.mkdirs();
                        }
                    }
                    taskInfo.setFilePath(filePath);
                    // end 设置存放文件的路径

                    // start 设置文件名
                    String fileName = taskInfo.getFileName();

                    if (TextUtils.isEmpty(fileName)) {
                        fileName = getFileName(con); // 根据http参数获取文件名
                    }
                    fileName.trim();
                    taskInfo.setFileName(fileName);

                    String ids = taskInfo.getBookid();
                    taskInfo.setBookid(ids);

                    // end 设置文件名

                    // start 设置下载文件
                    RandomAccessFile accessFile = new RandomAccessFile(
                            new File(taskInfo.getFilePath(), taskInfo.getFileName()), "rwd");
                    accessFile.setLength(len); // 设置文件长度
                    accessFile.close();
                    // end 设置下载文件
                    con.disconnect();
                    mHandler.sendMessage(mHandler.obtainMessage(MSG_INIT, taskInfo));

                } else {// 网址不正常。
                    dowload_id = taskInfo.getBookid();
                    mHandler.sendMessage(mHandler.obtainMessage(DIWLOAD_ERROY));
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取下载目录
     *
     * @return
     */
    private String getFilePath() {
        String path = null;

        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
                || !Environment.isExternalStorageRemovable()) {
            path = getExternalFilesDir(null).getAbsolutePath();

        } else {
            path = getFilesDir().getAbsolutePath();

        }
        File downloadFile = new File(path, DOWNLOAD_FILE);
        if (!downloadFile.exists()) {
            downloadFile.mkdirs();
        }
        path = downloadFile.getAbsolutePath();

        return path;

    }

    /**
     * 获取cup核心数
     *
     * @return
     */
    public static int getNumberOfCPUCores() {
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
            return 1;
        }
        int cores;
        try {
            cores = new File("/sys/devices/system/cpu/").listFiles(CPU_FILTER).length;
        } catch (SecurityException e) {
            cores = DEFAULT_CPU_CORES;
        } catch (NullPointerException e) {
            cores = DEFAULT_CPU_CORES;
        }
        return cores;
    }

    private static final FileFilter CPU_FILTER = new FileFilter() {
        @Override
        public boolean accept(File pathname) {
            String path = pathname.getName();
            if (path.startsWith("cpu")) {
                for (int i = 3; i < path.length(); i++) {
                    if (path.charAt(i) < '0' || path.charAt(i) > '9') {
                        return false;
                    }
                }
                return true;
            }
            return false;
        }
    };

    /**
     * 获取文件名
     *
     * @param conn
     * @return
     */
    private String getFileName(HttpURLConnection conn) {
        String filename = null;

        if (filename == null || "".equals(filename.trim())) {// 如果获取不到文件名称
            for (int i = 0; ; i++) {
                String mine = conn.getHeaderField(i);

                if (mine == null)
                    break;

                if ("content-disposition".equals(conn.getHeaderFieldKey(i).toLowerCase())) {
                    Matcher m = Pattern.compile(".*filename=(.*)").matcher(mine.toLowerCase());
                    if (m.find())
                        return m.group(1);
                }
            }

            filename = UUID.randomUUID() + "";// 默认取一个文件名
        }

        return filename;
    }

    /**
     * 接收下载完成的广播
     */
    class DownloadFinishedReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (null != action) {
                if (action.equals(ACTION_FINISHED)) {
                    String url = intent.getStringExtra(EXTRA_DOWNLOAD_URL);
                    mHandler.sendMessage(mHandler.obtainMessage(MSG_DOWNLOAD_FINISHED, url));
                }
            }
        }
    }

}
